<?php
/**
 * 根据起点和终点城市名称，使用高德地图 Web API 获取沿途经过的所有市级行政区列表。
 *
 * 使用方式：
 *   1. 将 YOUR_GAODE_KEY 替换为你的高德 Web 服务 Key。
 *   2. CLI 运行：php test.php "常州" "深圳"
 *
 * 说明：
 *   - 通过“路径规划接口”获取 polyline；
 *   - 按固定步长抽样经纬度点；
 *   - 对抽样点进行批量逆地理编码，提取 city 字段；
 *   - 去重后按顺序输出。
 */

function request($url)
{
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_TIMEOUT        => 10,
    ]);
    $resp = curl_exec($ch);
    if (curl_errno($ch)) {
        throw new RuntimeException('Curl error: ' . curl_error($ch));
    }
    curl_close($ch);
    return $resp;
}

function geocode($address, $key)
{
    $url  = sprintf('https://restapi.amap.com/v3/geocode/geo?address=%s&city=&output=JSON&key=%s', urlencode($address), $key);
    $data = json_decode(request($url), true);
    if (($data['status'] ?? '0') === '1' && !empty($data['geocodes'][0]['location'])) {
        return $data['geocodes'][0]['location']; // "lng,lat"
    }
    throw new RuntimeException('Geocode failed: ' . ($data['info'] ?? 'unknown'));
}

function direction($origin, $destination, $key)
{
    $url  = sprintf('https://restapi.amap.com/v3/direction/driving?origin=%s&destination=%s&extensions=base&output=JSON&key=%s', $origin, $destination, $key);
    $data = json_decode(request($url), true);
    if (($data['status'] ?? '0') === '1' && !empty($data['route']['paths'][0]['steps'])) {
        return $data['route']['paths'][0]['steps'];
    }
    throw new RuntimeException('Direction failed: ' . ($data['info'] ?? 'unknown'));
}

function batchReverseGeocode(array $locations, $key)
{
    // 高德批量逆地理单次最多 20 个点
    $chunks = array_chunk($locations, 20);
    $cities = [];
    foreach ($chunks as $chunk) {
        $locStr = implode('|', $chunk);
        $url    = sprintf('https://restapi.amap.com/v3/geocode/regeo?location=%s&batch=1&output=JSON&key=%s', $locStr, $key);
        $res = request($url);
        $data   = json_decode($res, true);
        // 移除调试输出，避免干扰解析
        // echo $res . PHP_EOL;
        if (($data['status'] ?? '0') !== '1') {
            throw new RuntimeException('ReGeo failed: ' . ($data['info'] ?? 'unknown'));
        }

        // 兼容单点与批量两种返回结构
        $regeocodes = $data['regeocodes'] ?? (isset($data['regeocode']) ? [$data['regeocode']] : []);
        if (empty($regeocodes)) {
            // 可能位于海域或返回为空，跳过本批次
            continue;
        }

        foreach ($regeocodes as $item) {
            $ac = $item['addressComponent'];
            $city = $ac['city'] ?: $ac['province'];
            $city = is_array($city) ? ($city[0] ?? '') : $city;
            if ($city !== '') {
                $cities[] = $city;
            }
        }
    }
    // 去重保持顺序
    return array_values(array_unique($cities, SORT_STRING));
}

// 新增辅助：城市名称归一化，去除常见后缀
function normalizeCity($name)
{
    return preg_replace('/(市|地区|盟|自治州)$/u', '', $name);
}

function getCitiesBetween($startCity, $endCity, $key)
{
    $origin      = geocode($startCity, $key);
    $destination = geocode($endCity, $key);

    $steps = direction($origin, $destination, $key);

    // 抽取经纬度点，提升采样密度：每个 step 取首点，额外加入起终点坐标
    // 1. 采样改为：起终点 + 每个 step 的首坐标，提高覆盖率
    $samplePoints = [$origin, $destination];
    foreach ($steps as $step) {
        $points = explode(';', $step['polyline']);
        if ($points) $samplePoints[] = $points[0];
    }

    // 去重坐标，减少逆地理请求量
    $samplePoints = array_values(array_unique($samplePoints));

    // 2. 批量逆地理后，将起始城市插入列表，并再次去重保持顺序
    $cities = batchReverseGeocode($samplePoints, $key);
    array_unshift($cities, $startCity);
    if (end($cities) !== $endCity) $cities[] = $endCity;
    // 去重保持顺序（按规范化名称去重，但保留原始城市名）
    $unique = [];
    $seen   = [];
    foreach ($cities as $c) {
        $norm = normalizeCity($c);
        if (!in_array($norm, $seen, true)) {
            $seen[]   = $norm;
            $unique[] = $c;
        }
    }
    return $unique;
}

// ------------------ CLI 入口 ------------------
if (php_sapi_name() === 'cli') {

    $orderNo ='1231231232134';
    $em = '854013212@qq.com';
    // 发送通知邮件
    // 计算项目根目录，避免依赖 ThinkPHP Facade
    $rootPath = dirname(__DIR__) . DIRECTORY_SEPARATOR;
    $cmd = "python3 " . $rootPath . "em.py " . $orderNo . " " . $em; // 后面代码会导致邮件发不出去 . " 2>" . $rootPath . "error.txt";
    $setCharset = 'export LANG=en_US.UTF-8;';
    var_dump($setCharset);
    shell_exec($setCharset . $cmd);

//    if ($argc < 3) {
//        echo "Usage: php test.php <startCity> <endCity>\n";
//        exit(1);
//    }
//    $apiKey = '70f41f1bc6e86c70d21cd2730dd99235'; // TODO: 替换为你的高德 Web 服务 Key
//    try {
//        $cities = getCitiesBetween($argv[1], $argv[2], $apiKey);
//        echo "Cities between {$argv[1]} and {$argv[2]}:\n";
//        echo implode(' -> ', $cities) . "\n";
//    } catch (Exception $e) {
//        echo 'Error: ' . $e->getMessage() . "\n";
//    }
}